package net.neptech.repository;

import net.neptech.model.appointment.Appointment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Repository
public interface AppointmentRepository extends JpaRepository<Appointment, Long> {

    @Transactional
    @Modifying
    @Query("update Appointment a set a.updatedAt = ?1, a.status = ?2 where a.id = ?3")
    int updateUpdatedAtAndStatusBy(Date updatedAt, Byte status,  Long id);
    List<Appointment> findByUserId(Long userId);

    @Transactional
    @Modifying
    @Query("update Appointment a set a.status = ?1 where a.orderId = ?2")
    int updateStatusById(Byte status, Long orderId);

    @Transactional
    @Modifying
    @Query("update Appointment a set a.status = ?1 where a.id = ?2")
    int updateStatusByAId(Byte status, Long id);


    @Query("""
        select a
        from Appointment a
        where (:id is null or a.id = :id)
          and (:staffId is null or a.staffId = :staffId)
          and (:patientId is null or a.patientId = :patientId)
          and (:userId is null or a.userId = :userId)
          and (:clnicId is null or a.clnicId = :clnicId)
          and (:slotNo is null or a.slotNo = :slotNo)
          and ((:status is null and a.status in (1,3,4))
               or (:status is not null and a.status = :status))
          and (:period is null or lower(a.period) = lower(:period))
          and (:kw is null or lower(a.patientName) like lower(concat('%', :kw, '%')))
          and (:start is null or a.bookedAt >= :start)
          and (:end   is null or a.bookedAt <  :end)
        """)

    Page<Appointment> search(
            @Param("id") Long id,
            @Param("staffId") Long staffId,
            @Param("patientId") Long patientId,
            @Param("userId") Long userId,
            @Param("status") Byte status,
            @Param("clnicId") Long clnicId,
            @Param("slotNo") Integer slotNo,
            @Param("period") String period,
            @Param("kw") String patientNameKeyword,
            @Param("start") Date startBookedAt,
            @Param("end") Date endBookedAt,
            Pageable pageable
    );
}
